module tcp_tx #(
    parameter   SOURCE_PORT     = 16'd5001                      ,
    parameter   SOURCE_IP       = {8'd192,8'd192,8'd7,8'd11    }
)(
    input                       i_clk                           ,
    input                       i_rst                           ,
    input                       i_set_source_port_valid         ,
    input  [15: 0]              i_set_source_port               ,
    input                       i_set_source_ip_valid           ,
    input  [31: 0]              i_set_source_ip                 ,
    input                       i_tcp_rx_valid                  , 
    input                       i_timer_250ms                   ,
    input                       i_timer_500ms                   ,
    input  [31: 0]              i_tcp_rx_id                     ,
    input  [31: 0]              i_tcp_rx_ack_id                 ,
    input  [5 : 0]              i_tcp_rx_flags                  ,
    input  [15: 0]              i_tcp_rx_windows_size           , 
    input                       s_axis_tvalid                   ,
    input  [7 : 0]              s_axis_tdata                    ,
    output                      s_axis_tready                   ,
    input                       s_axis_tlast                    ,
    input  [67: 0]              s_axis_tuser                    ,
    output                      m_axis_tvalid                   ,
    output [7 : 0]              m_axis_tdata                    ,
    input                       m_axis_tready                   ,
    output                      m_axis_tlast                    ,
    output [55: 0]              m_axis_tuser                      
);

    localparam P_GAP            = 5                             ;
    localparam TCP_PKG_TYPE     = 8'd6                          ; 

    logic   [15: 0]             set_source_port                 ;
    logic   [31: 0]             set_source_ip                   ;
    logic                       tcp_open                        ;
    logic                       tcp_close                       ;
    logic                       tcp_rx_valid                    ;
    logic   [31: 0]             tcp_rx_id                       ;
    logic   [31: 0]             tcp_rx_ack_id                   ;
    logic   [5 : 0]             tcp_rx_flags                    ;
    logic   [15: 0]             tcp_rx_windows_size             ;
    logic                       tcp_s_axis_tvalid               ;
    logic   [7 : 0]             tcp_s_axis_tdata                ;
    logic                       tcp_s_axis_tready               ;
    logic                       tcp_s_axis_tlast                ;
    logic   [67: 0]             tcp_s_axis_tuser                ;
    logic                       tcp_m_axis_tvalid               ;
    logic   [7 : 0]             tcp_m_axis_tdata                ;
    logic                       tcp_m_axis_tlast                ;
    logic   [55: 0]             tcp_m_axis_tuser                ; 
    logic                       tcp_setup_end                   ;
    logic                       tcp_setup_ack                   ;
    logic                       tcp_finish_end                  ;
    logic                       tcp_rx_close                    ;
    logic                       tcp_finish_ack                  ;
    logic   [15: 0]             over_time_cnt                   ;
    logic                       over_time_cnt_valid             ;
    logic   [15: 0]             over_time_list[4:0]             ;
    logic   [2 : 0]             over_time_list_index            ;
    logic                       over_time_flag                  ;
    logic   [15: 0]             lsm_cnt                         ;
    logic                       tcp_tx_req                      ;
    logic                       tcp_tx_end                      ;
    logic   [7 : 0]             tcp_tx_gap                      ;
    logic   [31: 0]             tcp_tx_id                       ;
    logic   [31: 0]             tcp_tx_ack_id                   ;
    logic   [5 : 0]             tcp_tx_flags                    ;
    logic   [15: 0]             tcp_tx_windows_size             ;
    logic   [31: 0]             tcp_tx_check_sum                ;
    logic   [31: 0]             tcp_tx_data_chechsum            ;
    logic   [3 : 0]             tcp_tx_head_len                 ;
    logic   [15: 0]             tcp_tx_mss                      ;
    logic   [15: 0]             tcp_tx_pkg_len                  ; 
    logic   [31: 0]             tcp_tx_target_ip                ;
    logic   [15: 0]             tcp_tx_target_port              ;

    

    typedef enum logic[3:0] {  
        ST_IDLE         ,
        ST_TX_SYN       ,
        ST_RX_SYN_ACK   ,
        ST_TX_ACK       ,
        ST_TX_DATA      ,
        ST_TX_FIN       ,
        ST_RX_FIN_ACK   ,
        ST_RX_FIN       ,
        ST_TX_FIN_ACK   ,
        ST_TX_RST       ,
        ST_RX_RST       
    } TCP_ST;

    TCP_ST c_tx_state;
    TCP_ST n_tx_state;

    ila128_bit ila128_bit_tcp_tx(
        .clk    ( i_clk),
        .probe0 ( {
            tcp_rx_valid,
            tcp_rx_flags,
                    tcp_open  ,
                    tcp_close ,
                    c_tx_state,
                    tcp_m_axis_tvalid,
                    tcp_m_axis_tdata ,
                    tcp_m_axis_tlast , 
                    tcp_setup_end    ,
                    tcp_setup_ack    ,
                    tcp_finish_end   ,
                    tcp_rx_close     ,
                    tcp_finish_ack   ,
                    over_time_cnt     ,     
                    over_time_cnt_valid    ,
                    over_time_list_index   ,
                    over_time_flag         ,
                    lsm_cnt                ,
                    tcp_tx_req             ,
                    tcp_tx_end             ,
                    tcp_tx_flags           ,
                    tcp_tx_windows_size    ,
                    tcp_tx_head_len        ,
                    tcp_tx_mss             ,
                    tcp_tx_pkg_len         


                  })

    );

    assign  over_time_list[0] = 12;
    assign  over_time_list[1] = 24;
    assign  over_time_list[2] = 48;
    assign  over_time_list[3] = 96;
    assign  over_time_list[4] = 192;
    

    assign s_axis_tready = tcp_s_axis_tready;
    assign m_axis_tvalid = tcp_m_axis_tvalid;
    assign m_axis_tdata = tcp_m_axis_tdata;
    assign m_axis_tlast = tcp_m_axis_tlast;
    assign m_axis_tuser = tcp_m_axis_tuser;


    //输入信号寄存
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            set_source_port <= SOURCE_PORT;
        else if(i_set_source_port_valid)
            set_source_port <= i_set_source_port;
        else 
            set_source_port <= set_source_port;  
    end
    
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            set_source_ip <= SOURCE_IP;
        else if(i_set_source_ip_valid)
            set_source_ip <= i_set_source_ip;
        else 
            set_source_ip <= set_source_ip;  
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst) begin
            tcp_rx_valid        <= 0;
            tcp_rx_id           <= 0;
            tcp_rx_ack_id       <= 0;
            tcp_rx_flags        <= 0;
            tcp_rx_windows_size <= 0;     
        end
        else if(i_tcp_rx_valid) begin
            tcp_rx_valid        <= 1                    ;
            tcp_rx_id           <= i_tcp_rx_id          ;
            tcp_rx_ack_id       <= i_tcp_rx_ack_id      ;
            tcp_rx_flags        <= i_tcp_rx_flags       ;
            tcp_rx_windows_size <= i_tcp_rx_windows_size;   
        end
        else begin
            tcp_rx_valid        <= 0                    ;
            tcp_rx_id           <= tcp_rx_id            ;
            tcp_rx_ack_id       <= tcp_rx_ack_id        ;
            tcp_rx_flags        <= tcp_rx_flags         ;
            tcp_rx_windows_size <= tcp_rx_windows_size  ;   
        end 
    end

     always_ff @( posedge i_clk ) begin
        if(i_rst) begin
            tcp_s_axis_tvalid<= 0;
            tcp_s_axis_tdata <= 0;
            tcp_s_axis_tlast <= 0;
            tcp_s_axis_tuser <= 0; 
        end
        else begin
            tcp_s_axis_tvalid<= s_axis_tvalid;
            tcp_s_axis_tdata <= s_axis_tdata ;
            tcp_s_axis_tlast <= s_axis_tlast ;
            tcp_s_axis_tuser <= s_axis_tuser ;  
        end
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst) begin
            tcp_open<= 0;
            tcp_close <= 0;
        end
        else if(s_axis_tvalid)begin
            tcp_open<= ~s_axis_tuser[65] & s_axis_tuser[64];
            tcp_close <= s_axis_tuser[65] & ~s_axis_tuser[64] ; 
        end
        else begin
            tcp_open <= 0;
            tcp_close <= 0;
        end 
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst) begin
            tcp_tx_target_ip <= 0;
            tcp_tx_target_port <= 0;
        end
        else if(s_axis_tvalid) begin
            tcp_tx_target_port <= s_axis_tuser[63:48];
            tcp_tx_target_ip <= s_axis_tuser[47:16];
        end
        else begin
            tcp_tx_target_ip <= tcp_tx_target_ip;
            tcp_tx_target_port <= tcp_tx_target_port;
        end
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_s_axis_tready <= 1;
        else 
            tcp_s_axis_tready <= tcp_s_axis_tready;  
    end

    //发包触发信号
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_req <= 0;
       else if(m_axis_tready && !tcp_tx_end && !tcp_tx_req && tcp_tx_gap == 0 &&
            (c_tx_state == ST_TX_SYN || c_tx_state == ST_TX_ACK ||
             c_tx_state == ST_TX_FIN || c_tx_state == ST_TX_FIN_ACK || 
             c_tx_state == ST_TX_RST))
            tcp_tx_req <= 1;
        else 
            tcp_tx_req <= 0;

    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_end <= 0;
        else if(tcp_m_axis_tlast)
            tcp_tx_end <= 0;
        else if(tcp_tx_req)
            tcp_tx_end <= 1;
        else 
            tcp_tx_end <= tcp_tx_end;

    end

    always_ff @( posedge i_clk ) begin
        if(i_rst) 
            tcp_tx_gap <= 0;
        else if(tcp_tx_gap == P_GAP - 1)
            tcp_tx_gap <= 0;
        else if(tcp_m_axis_tlast || tcp_tx_gap)
            tcp_tx_gap <= tcp_tx_gap + 1;
        else 
            tcp_tx_gap <= 0;

    end


   //三握手和四次挥手的控制逻辑
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_setup_ack <= 0;
        else if(c_tx_state == ST_TX_ACK)
            tcp_setup_ack <= 0; 
        else if(tcp_rx_valid && tcp_rx_flags != 6'b010010)
            tcp_setup_ack <= 0; 
        else if(tcp_rx_valid && tcp_rx_flags == 6'b010010)
            tcp_setup_ack <= 1; 
        else 
            tcp_setup_ack <= tcp_setup_ack;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_rx_close <= 0;
        else if(c_tx_state == ST_IDLE)
            tcp_rx_close <= 0; 
        else if(tcp_rx_valid && tcp_rx_flags == 6'b010001)
            tcp_rx_close <= 1; 
        else 
            tcp_rx_close <= tcp_rx_close;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_finish_ack <= 0;
        else if(c_tx_state == ST_IDLE)
            tcp_finish_ack <= 0; 
        else if(c_tx_state == ST_RX_FIN_ACK && tcp_rx_valid && tcp_rx_flags == 6'b010000)
            tcp_finish_ack <= 1; 
        else 
            tcp_finish_ack <= tcp_finish_ack;
    end

     //超时重传机制
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            over_time_cnt_valid <= 0;
        else if(c_tx_state == ST_RX_SYN_ACK || c_tx_state == ST_RX_FIN_ACK)
            over_time_cnt_valid <= 1; 
        else 
            over_time_cnt_valid <= 0; 
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            over_time_cnt <= 0;
        else if(!over_time_cnt_valid)
            over_time_cnt <= 0; 
        else if(over_time_cnt == over_time_list[over_time_list_index]-1)
            over_time_cnt <= 0; 
        else if(over_time_cnt_valid & i_timer_500ms)
            over_time_cnt <= over_time_cnt + 1; 
        else 
            over_time_cnt <= over_time_cnt;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            over_time_list_index <= 0;
        else if(c_tx_state == ST_TX_ACK)
            over_time_list_index <= 0; 
        else if(over_time_cnt == over_time_list[over_time_list_index]-1 && over_time_list_index == 4)
            over_time_list_index <= 0; 
        else if(over_time_cnt == over_time_list[over_time_list_index]-1)
            over_time_list_index <= over_time_list_index + 1; 
        else 
            over_time_list_index <= over_time_list_index;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            over_time_flag <= 0;
        else if(over_time_cnt == over_time_list[over_time_list_index]-1)
            over_time_flag <= 1; 
        else 
            over_time_flag <= 0;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_setup_end <= 0;
        else if(c_tx_state == ST_IDLE)
            tcp_setup_end <= 0;
        else if(over_time_cnt == over_time_list[over_time_list_index]-1 && over_time_list_index == 4)
            tcp_setup_end <= 1; 
        else 
            tcp_setup_end <= tcp_setup_end; 
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_finish_end <= 0;
        else if(c_tx_state == ST_IDLE)
            tcp_finish_end <= 0; 
        else if(c_tx_state == ST_TX_FIN_ACK)
            tcp_finish_end <= 1; 
        else 
            tcp_finish_end <= tcp_finish_end;
    end

    
   //tcp控制状态机

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            c_tx_state <= ST_IDLE;
        else 
            c_tx_state <= n_tx_state;  
    end

    always_comb begin 
        if(i_rst)
            n_tx_state = ST_IDLE;
        else 
            case (c_tx_state)
                ST_IDLE         : begin
                    if(tcp_open) 
                        n_tx_state = ST_TX_SYN;
                    else 
                        n_tx_state = ST_IDLE;
                end

                ST_TX_SYN       : begin
                    if(tcp_m_axis_tlast)
                        n_tx_state = ST_RX_SYN_ACK;
                    else 
                        n_tx_state = ST_TX_SYN;
                end

                ST_RX_SYN_ACK   : begin
                    //重传4次还没收到就发送复位
                    if(tcp_setup_end)
                        n_tx_state = ST_TX_RST;
                    //超时重传
                    else if(over_time_flag)
                        n_tx_state = ST_TX_SYN;
                    //收到sync_ack
                    else if(tcp_setup_ack)
                        n_tx_state = ST_TX_ACK;
                    else  
                        n_tx_state = ST_RX_SYN_ACK;
                end

                ST_TX_ACK       : begin
                    if(tcp_m_axis_tlast)
                        n_tx_state = ST_TX_DATA;
                    else  
                        n_tx_state = ST_TX_ACK;
                end

                ST_TX_DATA      : begin
                    //对面没有收到三次握手的ack包重新发起sync_ack
                    if(tcp_setup_ack)
                        n_tx_state = ST_TX_ACK;
                    //主动结束tcp通信
                    else if(tcp_close)
                        n_tx_state = ST_TX_FIN;
                    //收到对方的结束请求包
                    else if(tcp_rx_close)
                        n_tx_state = ST_TX_FIN_ACK;
                    else  
                        n_tx_state = ST_TX_DATA;
                end

                ST_TX_FIN       : begin
                    if(tcp_m_axis_tlast)
                        n_tx_state = ST_RX_FIN_ACK;
                    else  
                        n_tx_state = ST_TX_FIN;
                end

                ST_RX_FIN_ACK   : begin
                    //主动发送fin等待finack,此时tcp_finish_end还为0
                    if(tcp_finish_ack && !tcp_finish_end)
                        n_tx_state = ST_RX_FIN;
                    //被动接收fin，发送finack后等待finack，此时此时tcp_finish_end为1
                    else if(tcp_finish_ack && tcp_finish_end)
                        n_tx_state = ST_IDLE;
                    else 
                        n_tx_state = ST_RX_FIN_ACK;
                end

                ST_RX_FIN       : begin
                    if(tcp_rx_close)
                        n_tx_state = ST_TX_FIN_ACK;
                    else  
                        n_tx_state = ST_RX_FIN;
                end

                ST_TX_FIN_ACK   : begin
                    if(tcp_m_axis_tlast && tcp_finish_ack)
                        n_tx_state = ST_IDLE;
                    else if(tcp_m_axis_tlast && !tcp_finish_ack)
                        n_tx_state = ST_TX_FIN;
                    else  
                        n_tx_state = ST_TX_FIN_ACK;
                
                end

                ST_TX_RST       : begin
                     if(tcp_m_axis_tlast)
                        n_tx_state = ST_IDLE;
                    else  
                        n_tx_state = ST_TX_RST;
                end

                ST_RX_RST       : begin
                    n_tx_state = ST_IDLE;
                end

                default : n_tx_state = ST_IDLE;
            endcase
    end



    //组包，根据状态机填充各个字段

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_pkg_len <= 0;
        else if(c_tx_state == ST_TX_SYN)
            tcp_tx_pkg_len <= 24;
        else if(c_tx_state == ST_TX_ACK)
            tcp_tx_pkg_len <= 20;
        else if(c_tx_state == ST_TX_RST)
            tcp_tx_pkg_len <= 20;
        else if(c_tx_state == ST_TX_FIN)
            tcp_tx_pkg_len <= 20;
        else if(c_tx_state == ST_TX_FIN_ACK)
            tcp_tx_pkg_len <= 20;
        else  
            tcp_tx_pkg_len <= tcp_tx_pkg_len; 
    end
    
    
    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_id <= 12800;
        else if(c_tx_state == ST_TX_SYN && tcp_m_axis_tlast)
            tcp_tx_id <= tcp_tx_id + 1;
        else if(c_tx_state == ST_TX_FIN && tcp_m_axis_tlast)
            tcp_tx_id <= tcp_tx_id + 1;
        else  
            tcp_tx_id <= tcp_tx_id;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_ack_id <= 0;
        else if(tcp_rx_valid)
            tcp_tx_ack_id <= tcp_rx_id + 1;
        else  
            tcp_tx_ack_id <= tcp_tx_ack_id;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_flags <= 0;
        else if(c_tx_state == ST_TX_SYN)
            tcp_tx_flags <= 6'b000010;
        else if(c_tx_state == ST_TX_ACK)
            tcp_tx_flags <= 6'b010000;
        else if(c_tx_state == ST_TX_RST)
            tcp_tx_flags <= 6'b010100;
        else if(c_tx_state == ST_TX_FIN)
            tcp_tx_flags <= 6'b010001;
        else if(c_tx_state == ST_TX_FIN_ACK)
            tcp_tx_flags <= 6'b010000;
        else  
            tcp_tx_flags <= tcp_tx_flags;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_windows_size <= 0;
        else  
            tcp_tx_windows_size <= 16'd65535;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_head_len <= 0;
        else if(c_tx_state == ST_TX_SYN)
            tcp_tx_head_len <= 'd6;
        else if(c_tx_state == ST_TX_ACK)
            tcp_tx_head_len <= 'd5;
        else if(c_tx_state == ST_TX_RST)
            tcp_tx_head_len <= 'd5;
        else if(c_tx_state == ST_TX_FIN)
            tcp_tx_head_len <= 'd5;
        else if(c_tx_state == ST_TX_FIN_ACK)
            tcp_tx_head_len <= 'd5;
        else  
            tcp_tx_head_len <= tcp_tx_head_len;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_mss <= 0;
        else  
            tcp_tx_mss <= 16'd1024;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_data_chechsum <= 0;
        else  
            tcp_tx_data_chechsum <= tcp_tx_data_chechsum;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_tx_check_sum <= 0;
        else if(tcp_tx_req)//伪TCP首部：源IP（32）+目的IP（32）+总长度（16）+TCP协议（8）
            tcp_tx_check_sum <= set_source_ip[31:16] + set_source_ip[15:0] + tcp_tx_target_ip[31:16] + tcp_tx_target_ip[15:0]
                   + tcp_tx_pkg_len + 16'd6;
        else if(c_tx_state == ST_TX_SYN && lsm_cnt == 1)
            tcp_tx_check_sum <= tcp_tx_check_sum + set_source_port + tcp_tx_target_port + tcp_tx_id[31:16] + tcp_tx_id[15:0] + tcp_tx_ack_id[31:16] + tcp_tx_ack_id[15:0]
                    + {{tcp_tx_head_len,4'd0},{2'd0,tcp_tx_flags}} + tcp_tx_windows_size + {8'd2,8'd4} + tcp_tx_mss;
        else if(c_tx_state != ST_TX_SYN && lsm_cnt == 1)
            tcp_tx_check_sum <= tcp_tx_check_sum + set_source_port + tcp_tx_target_port + tcp_tx_id[31:16] + tcp_tx_id[15:0] + tcp_tx_ack_id[31:16] + tcp_tx_ack_id[15:0]
                    + {{tcp_tx_head_len,4'd0},{2'd0,tcp_tx_flags}} + tcp_tx_windows_size;
        else if(lsm_cnt == 2)
            tcp_tx_check_sum <= tcp_tx_check_sum + tcp_tx_data_chechsum;
        else if(lsm_cnt == 3)
            tcp_tx_check_sum <= tcp_tx_check_sum[31:16] + tcp_tx_check_sum[15:0];
        else if(lsm_cnt == 4)
            tcp_tx_check_sum <= tcp_tx_check_sum[31:16] + tcp_tx_check_sum[15:0];
        else if(lsm_cnt == 5)
            tcp_tx_check_sum <= ~tcp_tx_check_sum;
        else  
            tcp_tx_check_sum <= tcp_tx_check_sum;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            lsm_cnt <= 0;
        else if(lsm_cnt == tcp_tx_pkg_len-1)
            lsm_cnt <= 0;
        else if(tcp_tx_req || (lsm_cnt && m_axis_tready))
            lsm_cnt <= lsm_cnt + 1;
        else  
            lsm_cnt <= lsm_cnt;
    end

    //输出控制

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_m_axis_tdata <= 0;
        else  
            case (lsm_cnt)
                0 : tcp_m_axis_tdata <= set_source_port[15: 8];
                1 : tcp_m_axis_tdata <= set_source_port[7 : 0];
                2 : tcp_m_axis_tdata <= tcp_tx_target_port[15: 8];
                3 : tcp_m_axis_tdata <= tcp_tx_target_port[7 : 0];
                4 : tcp_m_axis_tdata <= tcp_tx_id[31:24];
                5 : tcp_m_axis_tdata <= tcp_tx_id[23:16];
                6 : tcp_m_axis_tdata <= tcp_tx_id[15: 8];
                7 : tcp_m_axis_tdata <= tcp_tx_id[7 : 0];
                8 : tcp_m_axis_tdata <= tcp_tx_ack_id[31:24];
                9 : tcp_m_axis_tdata <= tcp_tx_ack_id[23:16];
                10 :tcp_m_axis_tdata <= tcp_tx_ack_id[15: 8];
                11 :tcp_m_axis_tdata <= tcp_tx_ack_id[7 : 0];
                12 :tcp_m_axis_tdata <= {tcp_tx_head_len, 4'd0};
                13 :tcp_m_axis_tdata <= {2'd0, tcp_tx_flags};
                14 :tcp_m_axis_tdata <= tcp_tx_windows_size[15:8];
                15 :tcp_m_axis_tdata <= tcp_tx_windows_size[7: 0];
                16 :tcp_m_axis_tdata <= tcp_tx_check_sum[15:8];
                17 :tcp_m_axis_tdata <= tcp_tx_check_sum[7:0];
                18 :tcp_m_axis_tdata <= 0;
                19 :tcp_m_axis_tdata <= 0;
                20 :tcp_m_axis_tdata <= 2;//mss kind
                21 :tcp_m_axis_tdata <= 4;//mss length
                22 :tcp_m_axis_tdata <= tcp_tx_mss[15: 8];
                23 :tcp_m_axis_tdata <= tcp_tx_mss[7: 0];
                default : tcp_m_axis_tdata <= 0;
            endcase
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_m_axis_tvalid <= 0;
        else if(tcp_m_axis_tvalid & tcp_m_axis_tlast)
            tcp_m_axis_tvalid <= 0;
        else if(tcp_tx_req & m_axis_tready)
            tcp_m_axis_tvalid <= 1;
        else  
            tcp_m_axis_tvalid <= tcp_m_axis_tvalid;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_m_axis_tlast <= 0;
        else if(lsm_cnt == tcp_tx_pkg_len-1)
            tcp_m_axis_tlast <= 1;
        else  
            tcp_m_axis_tlast <= 0;
    end

    always_ff @( posedge i_clk ) begin
        if(i_rst)
            tcp_m_axis_tuser <= 0;
        else if(tcp_tx_req & m_axis_tready)
            tcp_m_axis_tuser <= {tcp_tx_target_ip,TCP_PKG_TYPE,tcp_tx_pkg_len};
        else  
            tcp_m_axis_tuser <= tcp_m_axis_tuser;
    end





endmodule 


